#include "bsp_hcsr04.h"
#include "rtdef.h"


uint64_t time_count = 0;			//声明变量，用来计时

 
static void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_Periph_TIMER, ENABLE);				//启用TIMER时钟

	TIM_InternalClockConfig(TIMER);									//设置启用TIMER时钟使用内部时钟
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0};
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;		//设置1分频（不分频）
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;	//设置计数模式为向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 10 - 1;					//设置最大计数值，达到最大值触发更新事件，因为从0开始计数，所以计数10次是10-1,每10微秒触发一次
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;				//设置时钟预分频，72-1就是每时钟频率(72Mhz)/72=1000000 个时钟周期计数器加1,每1微秒+1
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;			//重复计数器（高级定时器才有，所以设置0）
	TIM_TimeBaseInit(TIMER, &TIM_TimeBaseInitStructure);			//初始化TIMER定时器
	
	TIM_ITConfig(TIMER, TIM_IT_Update, ENABLE);						//开启更新中断
	TIM_ClearFlag(TIMER, TIM_FLAG_Update);							//清除更新中断标志位

	NVIC_InitTypeDef NVIC_InitStructure = {0};						//定义结构体，配置中断优先级
	NVIC_InitStructure.NVIC_IRQChannel = TIMER_IRQn;				//指定中断通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//中断使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	//设置抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;			//设置响应优先级
	NVIC_Init(&NVIC_InitStructure);								
	TIM_SetCounter(TIMER, 0);
}




void HC_SR04_Init(void)
{
	Timer_Init();
#if REMAP_SWJ_JTAG
	RCC_APB2PeriphClockCmd(RCC_GPIO_Port | RCC_APB2Periph_AFIO, ENABLE);	 // 复用了Jlink的调试端口
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
#else
	RCC_APB2PeriphClockCmd(RCC_GPIO_Port, ENABLE);		//启用GPIOB的外设时钟
#endif
	GPIO_InitTypeDef GPIO_InitStructure = {0};					//定义结构体
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;			//设置GPIO口为推挽输出
	GPIO_InitStructure.GPIO_Pin = Trig_Pin;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;			//设置GPIO口速度50Mhz
	GPIO_Init(Trig_Port, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;				//设置GPIO口为下拉输入模式
	GPIO_InitStructure.GPIO_Pin = Echo_Pin;
	GPIO_Init(Echo_Port, &GPIO_InitStructure);
	GPIO_WriteBit(Echo_Port, Echo_Pin, Bit_RESET);				//输出低电平
}




int32_t HC_SR04_GetDistance_mm(void)											//测距并返回单位为毫米的距离结果
{
	uint32_t Distance_mm = 0;
	GPIO_WriteBit(Trig_Port, Trig_Pin, Bit_SET);				//输出高电平
	Delay_15us();												//延时15微秒
	GPIO_WriteBit(Trig_Port, Trig_Pin, Bit_RESET);				//输出低电平
	
	
#if 	PREVENT_STUCK
	uint32_t a = 0;
	while(GPIO_ReadInputDataBit(Echo_Port, Echo_Pin) == 0)
	{
		a++;
		if(a > 1000000) return -1; // 返回错误
	}		//等待低电平结束
	a = 0;
	TIM_Cmd(TIMER, ENABLE);
	while(GPIO_ReadInputDataBit(Echo_Port, Echo_Pin) == 1)
	{
		a++;
		if(a > 1000000) return -1; // 返回错误
	}		//等待高电平结束

#else
	
	while(GPIO_ReadInputDataBit(Echo_Port, Echo_Pin) == 0);
	time_count = 0;
	TIM_Cmd(TIMER, ENABLE);
	while(GPIO_ReadInputDataBit(Echo_Port, Echo_Pin) == 1);
	
#endif
	
	TIM_Cmd(TIMER, DISABLE);
	TIM_SetCounter(TIMER, 0);
	//计算距离，声音在空气中的传播速度大概是340每秒，因为上面的time_end的单位是10微秒
	// 所以要得出单位为毫米的距离结果，还得除以200
	Distance_mm = (time_count*340)/200;
	time_count = 0;										//记录结束时的时间
	if (Distance_mm > 6*1000) return -1;
	return Distance_mm;
}

// TIMER_IRQn_FUN
// 每10微妙进入一次
void TIMER_IRQn_FUN(void)                
{                                                    
    if (TIM_GetITStatus(TIMER, TIM_IT_Update) == SET)
    {                                                
        time_count++;                                
        TIM_ClearITPendingBit(TIMER, TIM_IT_Update); 
    }                                                
}        

